home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’97 / WhereTheHellWasIReading? / source code / WhereTheHellINIT.c < prev    next >
C/C++ Source or Header  |  1997-06-28  |  9KB  |  318 lines

  1. // hi there
  2.  
  3. // Copyright © 1997 Pierre Houston. All rights reserved.
  4. // or something like that
  5.  
  6. // Portions copied from RandomFinderStrings, Mike Scanlin. 24 Jan 1993
  7.  
  8. #ifndef __TYPES__
  9. #    include <Types.h>
  10. #endif
  11.  
  12. #ifndef __QUICKDRAW__
  13. #    include <Quickdraw.h>
  14. #endif
  15.  
  16. #ifndef __OSUTILS__
  17. #    include <OSUtils.h>
  18. #endif
  19.  
  20. #ifndef __WINDOWS__
  21. #    include <Windows.h>
  22. #endif
  23.  
  24. #ifndef __MEMORY__
  25. #    include <Memory.h>
  26. #endif
  27.  
  28. #ifndef __LOWMEM__
  29. #    include <LowMem.h>
  30. #endif
  31.  
  32. #include "ShowInitIcon.h"
  33.  
  34.  
  35. #define rLoadBadIcon 128
  36. #define rLoadOKIcon1 129
  37. #define rLoadOKIcon2 130
  38. #define rLoadOKIcon3 131
  39. #define rLoadOKIcon4 132
  40. #define rLoadOKIcon5 133
  41. #define rLoadOKIcon6 134
  42. #define rLoadOKIcon7 135
  43.  
  44. typedef pascal void (*ScrollRectProcPtr)(const Rect *r, short dh, short dv, RgnHandle rgn);
  45. struct PatchGlobals {
  46.     ScrollRectProcPtr    oldScrollRect;
  47.     RgnHandle            savedClipRgn;
  48.     RgnHandle            tempRgn;
  49.     unsigned long        flags;
  50. };
  51. typedef struct PatchGlobals PatchGlobals, *PatchGlobalsPtr;
  52.  
  53. #define HACKOFF 1
  54. #define HACKMOREOFTEN 2
  55. #define INVERTHACKRECTS 3
  56.  
  57. pascal void MyScrollRect(const Rect *r, short dh, short dv, RgnHandle rgn);
  58. void FibonacciScrollMagic(short a, short b, short sum, short count, Boolean up, const Rect *r, GrafPtr pPort);
  59. void StartPatchCode(void);
  60. void EndPatchCode(void);
  61.  
  62. pascal void main()
  63. {
  64.     // anyone know how to make a fat patch??
  65.     
  66.     Ptr             patchPtr;
  67.     PatchGlobalsPtr pgPtr;
  68.     long            codeSize, offset;
  69.     long            time;
  70.     
  71.     /* try and get some memory in the system heap
  72.      * for code and globals */
  73.     codeSize = (long) EndPatchCode - (long) StartPatchCode;
  74.     patchPtr = NewPtrSys(codeSize + sizeof(PatchGlobals));
  75.     if (!patchPtr)
  76.         return; /* out of memory--abort patching */
  77.     
  78.     /* initialize the patch globals at the
  79.      * beginning of the block */
  80.     pgPtr = (PatchGlobalsPtr) patchPtr;
  81.     pgPtr->oldScrollRect = (ScrollRectProcPtr) NGetTrapAddress(_ScrollRect, ToolTrap);
  82.     
  83.     // alloc a region first time we hit our patch
  84.     pgPtr->savedClipRgn = 0L;
  85.     pgPtr->tempRgn = 0L;
  86.     pgPtr->flags = 0;
  87.     
  88.     /* move the code into place after the globals */
  89.     BlockMove(StartPatchCode, patchPtr + sizeof(PatchGlobals), codeSize);
  90.     
  91.     /* set the patches */
  92.     patchPtr += sizeof(PatchGlobals);
  93.     offset = (long) MyScrollRect - (long) StartPatchCode;
  94.     NSetTrapAddress((UniversalProcPtr) (patchPtr + offset), _ScrollRect, ToolTrap);
  95.     
  96.     // call ShowInitIcon
  97.     ShowInitIcon(rLoadOKIcon1, false);
  98.     Delay(26, &time);
  99.     ShowInitIcon(rLoadOKIcon2, false);
  100.     Delay(12, &time);
  101.     ShowInitIcon(rLoadOKIcon3, false);
  102.     Delay(12, &time);
  103.     ShowInitIcon(rLoadOKIcon4, false);
  104.     Delay(15, &time);
  105.     ShowInitIcon(rLoadOKIcon5, false);
  106.     Delay(18, &time);
  107.     ShowInitIcon(rLoadOKIcon6, false);
  108.     Delay(20, &time);
  109.     ShowInitIcon(rLoadOKIcon7, true);
  110.     
  111.     {
  112.         Str255 str;
  113.         KeyMap keys;
  114.         GetKeys(keys);
  115.         if (keys[1] & 0x8)
  116.         {
  117.             pgPtr->flags |= HACKOFF;                    // turn hack off
  118.             NumToString((long) &pgPtr->flags, &str[5]);
  119.             *(unsigned long*) &str[1] = ';dl ';            // prepend ';dl ' to string
  120.             str[0] = str[5] + 5;
  121.             str[5] = '#';
  122.             DebugStr(str);
  123.         }
  124.     }
  125. }
  126.  
  127.  
  128. void StartPatchCode()
  129. {
  130. }
  131.  
  132. pascal void MyScrollRect(const Rect *r, short dh, short dv, RgnHandle rgn)
  133. {
  134.     PatchGlobalsPtr pgPtr;
  135.     GrafPtr pPort;
  136.     short scrollDistance;
  137.     short fontHeight;
  138.     ControlHandle windowControl;
  139.     int windowControlDistance;
  140.     Boolean doAnim = false;
  141.     Rect tempRect;
  142.     
  143.     /* find our globals */
  144.     pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
  145.     
  146.     if (!(pgPtr->flags & HACKOFF))
  147.     {
  148.         GetPort(&pPort);
  149.         fontHeight = 16;    // %%% HACK! :-)
  150.         scrollDistance = dv < 0 ? -dv : dv;
  151.         
  152.         // how do we tell its a document paging down?
  153.         // if the port is the frontmost window and rect is about the size of a vertical scrollbar
  154.         // in the window and its scrolling vertically more than a couple lines of text, and less
  155.         // than almost the entire height
  156.         
  157.         if (!dh && pPort == FrontWindow()
  158.          && scrollDistance <= r->bottom - r->top - fontHeight
  159.          && (pgPtr->flags & HACKMOREOFTEN || scrollDistance >= fontHeight * 3))
  160.         {
  161.             #if 0
  162.             // look for a vertical scrollbar in the window
  163.             // if we don't do this, then maybe the app, for example, is scrolling down a portion of
  164.             // the visible document while its inserting another line
  165.             
  166.             windowControl = ((WindowPeek) pPort)->controlList;
  167.             while (windowControl)
  168.             {
  169.                 // if correct width and at least the minimum height, it might be a scroll bar
  170.                 if (tempRect.right - tempRect.left == 16 && tempRect.bottom - tempRect.top >= 48)
  171.                 {
  172.                     // if control is nearly right beside the scroll rect, lets just say it probably is
  173.                     // a scroll bar and we'll do the scrolling animation (woohoo)
  174.                     tempRect = (**windowControl).contrlRect;
  175.                     windowControlDistance = tempRect.left - r->right;
  176.                     if ((windowControlDistance < 0 ? -windowControlDistance : windowControlDistance) < 3)
  177.                     {
  178.                         doAnim = true;
  179.                         break;
  180.                     }
  181.                 }
  182.                 windowControl = (**windowControl).nextControl;
  183.             }
  184.             
  185.             if (!doAnim) SysBeep(10);
  186.             #else
  187.                 doAnim = true;
  188.             #endif
  189.         }
  190.     }
  191.     
  192.     if (doAnim)
  193.     {
  194.         // do the animation
  195.         FibonacciScrollMagic(0, 1, 1, scrollDistance, dv < 0, r, pPort);
  196.         
  197.         // clip out the destination rect so the real ScrollRect doesn't scroll it again
  198.         if (!pgPtr->savedClipRgn)
  199.             pgPtr->savedClipRgn = NewRgn();
  200.         if (!pgPtr->tempRgn)
  201.             pgPtr->tempRgn = NewRgn();
  202.         CopyRgn(pPort->clipRgn, pgPtr->savedClipRgn);
  203.         RectRgn(pgPtr->tempRgn, r);
  204.         OffsetRgn(pgPtr->tempRgn, 0, dv);
  205.         DiffRgn(pPort->clipRgn, pgPtr->tempRgn, pPort->clipRgn);
  206.         
  207.         if (pgPtr->flags & INVERTHACKRECTS)
  208.         {
  209.             long time;
  210.             
  211.             InvertRect(&tempRect);
  212.             Delay(30, &time);
  213.             InvertRect(&tempRect);
  214.             
  215.             InvertRgn(pPort->clipRgn);
  216.             Delay(30, &time);
  217.             InvertRgn(pPort->clipRgn);
  218.         }
  219.         
  220.         /* call the real ScrollRect */
  221.         (*pgPtr->oldScrollRect)(r, dh, dv, rgn);
  222.         
  223.         // restore the clip region
  224.         CopyRgn(pgPtr->savedClipRgn, pPort->clipRgn);
  225.     }
  226.     else
  227.     {
  228.         /* call the real ScrollRect */
  229.         (*pgPtr->oldScrollRect)(r, dh, dv, rgn);
  230.     }
  231. }
  232.  
  233. void FibonacciScrollMagic(short a, short b, short sum, short count, Boolean up, const Rect *r, GrafPtr pPort)
  234. {
  235.     if (sum + a + b >= count)
  236.     {
  237.         // the next recursion would be too far, so exit the recursion and start scrolling
  238.         // scroll by b pixels plus the remainder
  239.         // (scrolling only b pixels & returning will end up scrolling an offset equal to sum
  240.         // so the remainder is the amount that would be left over: count - sum)
  241.         b += count - sum;
  242.         sum = count;
  243.     }
  244.     else
  245.     {
  246.         // we will scroll b pixels
  247.         // do the scroll for this iteration last, so the largest amount is scrolled first
  248.         FibonacciScrollMagic(b, a + b, sum + a + b, count, up, r, pPort);
  249.     }
  250.     
  251.     // begin another block here so the compiler can guess not to leave stack space for these
  252.     // local vars during all that recursion above. if we do leave this stack space before the
  253.     // recursion, then theres space left at every iteration. waste stack not or want stack not.
  254.     
  255.     {
  256.         // pick the pixels to scroll this iteration
  257.         // we also have to erase the pixels that are left behind
  258.         // sum is the number of pixels this and earlier iterations will scroll in total
  259.         // so the offset that has already been scrolled should be count - sum
  260.         // use this info do we don't have to scroll pixels already erased in past iterations
  261.         Rect rDst;
  262.         Rect rSrc = *r;
  263.         Rect rWake;                        // ie. the pixels in our wake
  264.         if (up)
  265.         {
  266.             rSrc.top += b;                // pixels up here would get copied up out of portRect
  267.             rSrc.bottom -= count - sum;    // pixels down here have already been erased
  268.             
  269.             rDst = rSrc;
  270.             OffsetRect(&rDst, 0, -b);    // negative value to offset coordinates up
  271.             
  272.             rWake = rSrc;
  273.             rWake.top = rDst.bottom;    // erase the pixels that won't get copied over
  274.         }
  275.         else
  276.         {
  277.             rSrc.top += count - sum;    // pixels up here have already been erased
  278.             rSrc.bottom -= b;            // pixels down here would get copied down out of portRect
  279.             
  280.             rDst = rSrc;
  281.             OffsetRect(&rDst, 0, b);    // positive value to offset coordinates down
  282.             
  283.             rWake = rSrc;
  284.             rWake.bottom = rDst.top;    // erase the pixels that won't get copied over
  285.         }
  286.         
  287.         CopyBits(&pPort->portBits, &pPort->portBits, &rSrc, &rDst, srcCopy, NULL);
  288.         EraseRect(&rWake);
  289.         
  290.         #if 0
  291.         if (!a)
  292.         {
  293.             long time;
  294.             /*InvertRect(&rSrc);
  295.             Delay(6, &time);
  296.             InvertRect(&rSrc);
  297.             Delay(15, &time);*/
  298.             InvertRect(&rDst);
  299.             Delay(6, &time);
  300.             InvertRect(&rDst);
  301.             /*Delay(15, &time);
  302.             InvertRect(&rWake);
  303.             Delay(6, &time);
  304.             InvertRect(&rWake);*/
  305.             Delay(20, &time);
  306.         }
  307.         #endif
  308.         
  309.         // if this happens to be the first iteration, we will never scroll a pixels
  310.         // thats why the caller should call the first iteration with a=0, b=1
  311.     }
  312. }
  313.  
  314. void EndPatchCode()
  315. {
  316. }
  317.  
  318.